package com.example.controller;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.unit.DataUnit;
import cn.hutool.core.lang.Dict;
import com.example.common.Result;
import com.example.common.enums.RoleEnum;
import com.example.entity.*;
import com.example.mapper.ArticleMapper;
import com.example.mapper.OrdersMapper;
import com.example.mapper.TourismMapper;
import com.example.mapper.TravelsMapper;
import com.example.service.AdminService;
import com.example.service.UserService;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

@RestController
public class WebController {

    @Resource
    private AdminService adminService;

    @Resource
    private UserService userService;

    @Resource
    private TravelsMapper travelsMapper;

    @Resource
    private ArticleMapper articleMapper;

    @Resource
    private TourismMapper tourismMapper;

    @Resource
    private OrdersMapper ordersMapper;

    /**
     * 默认请求接口 - 用来验证后端有没有启动成功
     */
    @GetMapping("/")
    public Result hello() {
        return Result.success();
    }

    /**
     * 登录
     */
    @PostMapping("/login")
    public Result login(@RequestBody Account account) { //Account是通用的角色的基类
        Account loginAccount = null;
        if (RoleEnum.ADMIN.name().equals(account.getRole())) { //只有管理员角色登录的时候才会调用adminService
            loginAccount = adminService.login(account); // todo 笔记：Account是Admin的父类，可以接收Admin中所有属性的信息
        } else  if (RoleEnum.USER.name().equals(account.getRole())) {
            loginAccount = userService.login(account);
        }
        return Result.success(loginAccount);
    }

    /**
     * 注册 --- 根据具体的项目不同，需注册的用户角色不同
     */
    @PostMapping("/register")
    public Result register(@RequestBody User user) {
        userService.add(user);
        return Result.success();
    }

    /**
     * 修改密码
     */
    @PutMapping("/updatePassword")
    public Result updatePassword(@RequestBody Account account) {
        if (RoleEnum.ADMIN.name().equals(account.getRole())) { //不同的角色修改密码的逻辑不一样
            adminService.updatePassword(account);
        } else if (RoleEnum.USER.name().equals(account.getRole())) {
            userService.updatePassword(account);
        }
        return Result.success();
    }

    /**
     * 统计 游记、攻略、商品、订单 总数
     */
    @GetMapping("/count")
    public Result count() {
        long travelsCount = travelsMapper.selectAll(null).size(); //游记总数
        long articleCount = articleMapper.selectAll(null).size(); //攻略总数
        long tourismCount = tourismMapper.selectAll(null).size(); //商品种类数
//        long ordersCount = ordersMapper.selectAll(null).size(); //订单总数
        long ordersCount = ordersMapper.selectAll(null).stream().map(Orders::getNum).reduce(Integer::sum).orElse(0); //订单总数

        Dict dict = Dict.create().set("travelsCount", travelsCount)
                .set("articleCount", articleCount)
                .set("tourismCount", tourismCount)
                .set("ordersCount", ordersCount); //Dick其实就是一个map集合
        return Result.success(dict);
    }

    /**
     * 统计旅游商品在最近一个月每天的销售量
     */
    @GetMapping("/selectOrdersData")
    public Result selectOrdersData() {
        Date date = new Date();
        DateTime start = DateUtil.offsetDay(date, -31); //开始日期：31天前
        DateTime end = DateUtil.offsetDay(date, -1); //结束日期：昨天

        //得到最近一个月的字符串日期集合 ["2024-11-29", "2024-11-30", ...]
        /**
         * DAY_OF_YEAR - 这一年的时间单位
         * DateUtil::formatDate - 将日期时间格式变成字符串形式的日期格式
         * Comparator.naturalOrder() - 按照自然排序（即从小到大排序）
         */
        List<String> dateList = DateUtil.rangeToList(start, end, DateField.DAY_OF_YEAR).stream().map(DateUtil::formatDate)
                .sorted(Comparator.naturalOrder()).toList();

        //构造返回值
        List<Dict> dictList = new ArrayList<>();

        //计算出每一天的销售额（即买了多少旅游商品）
        List<Orders> ordersList = ordersMapper.selectAll(null); //todo 笔记：查询所有的语句最好不要放在for循环里面
        for (String day : dateList) {
            /**
             * reduce(Integer::sum) - 求和
             * orElse(0) - 如果当前没卖出商品，则为0
             */
            Integer orderNum = ordersList.stream().filter(orders -> orders.getTime().contains(day))
                    .map(Orders::getNum).reduce(Integer::sum).orElse(0);
            Dict dict = Dict.create().set("date", day).set("orderNum", orderNum);
            dictList.add(dict);
        }
        System.out.println(dictList);

        return Result.success(dictList);
    }

    /**
     * 统计最近一个月，所有用户每天发布的游记数量
     */
    @GetMapping("/selectTravelsData")
    public Result selectTravelsData() {
        Date date = new Date();
        DateTime start = DateUtil.offsetDay(date, -31); //开始日期：31天前
        DateTime end = DateUtil.offsetDay(date, -1); //结束日期：昨天

        //得到最近一个月的字符串日期集合 ["2024-11-29", "2024-11-30", ...]
        /**
         * DAY_OF_YEAR - 这一年的时间单位
         * DateUtil::formatDate - 将日期时间格式变成字符串形式的日期格式
         * Comparator.naturalOrder() - 按照自然排序（即从小到大排序）
         */
        List<String> dateList = DateUtil.rangeToList(start, end, DateField.DAY_OF_YEAR).stream().map(DateUtil::formatDate)
                .sorted(Comparator.naturalOrder()).toList();

        //构造返回值
        List<Dict> dictList = new ArrayList<>();

        //计算出每一天的发布的游记数量
        List<Travels> travelsList = travelsMapper.selectAll(null);
        for (String day : dateList) {
            long travelsNum = travelsList.stream().filter(travels -> travels.getTime().contains(day))
                    .count();
            Dict dict = Dict.create().set("date", day).set("travelsNum", travelsNum);
            dictList.add(dict);
        }
        System.out.println(dictList);

        return Result.success(dictList);
    }
}
